﻿namespace MefContrib.Models.Provider.Tests
{
    using System;
    using System.Collections.Generic;
    using System.Reflection;
    using NUnit.Framework;

    [TestFixture]
    public class ProviderImportDefinitionTests
    {
        private MemberInfo GetDummyMemberInfo()
        {
            var memberInfo = MemberInfoServices.GetMemberInfo(typeof(DummyPart).AssemblyQualifiedName, "DummyImport");
            return memberInfo;
        }

        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void ConstructorShouldThrowExceptionIfMemberParameterIsNull()
        {
            var import = new ProviderImportDefinition(null, null);
        }

        [Test, ExpectedException(typeof(ArgumentNullException))]
        public void ConstructorShouldThrowExceptionIfImportDefinitionIsNull()
        {
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), null);
        }
        
        [Test]
        public void ConstructorShouldNotThrowExceptionIfContractNameAndContractTypeAreEmpty()
        {
            var importDescription = new ImportDescription();
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.That(import.ContractName, Is.EqualTo("System.String"));
        }

        [Test]
        public void ConstructorShouldNotThrowExceptionIfRequiredMetadataIsNull()
        {
            var importDescription = new ImportDescription { ContractName = "contract" };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.IsTrue(true);
        }

        [Test]
        public void AllowDefaultShouldReturnFalseIfPassedFalseInConstructor()
        {
            var importDescription = new ImportDescription { ContractName = "contract", AllowDefault = false };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.IsFalse(import.AllowDefault);
        }

        [Test]
        public void AllowDefaultShouldReturnTrueIfPassedTrueInConstructor()
        {
            var importDescription = new ImportDescription { ContractName = "contract", AllowDefault = true };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.IsTrue(import.AllowDefault);
        }

        [Test]
        public void IsRecomposableShouldReturnFalseIfPassedFalseInConstructor()
        {
            var importDescription = new ImportDescription { ContractName = "contract", Recomposable = false };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.IsFalse(import.IsRecomposable);
        }

        [Test]
        public void IsRecomposableShouldReturnTrueIfPassedTrueInConstructor()
        {
            var importDescription = new ImportDescription { ContractName = "contract", Recomposable = true };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.IsTrue(import.IsRecomposable);
        }

        [Test]
        public void IsPrerequisiteShouldReturnFalseIfPassedFalseInConstructor()
        {
            var importDescription = new ImportDescription { ContractName = "contract", Prerequisite = false };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.IsFalse(import.IsPrerequisite);
        }

        [Test]
        public void IsPrerequisiteShouldReturnTrueIfPassedTrueInConstructor()
        {
            var importDescription = new ImportDescription { ContractName = "contract", Prerequisite = true };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.IsTrue(import.IsPrerequisite);
        }

        [Test]
        public void RequiredMetadataShouldBeEmptyEnumerableIfPassedNullInConstructor()
        {
            var importDescription = new ImportDescription { ContractName = "contract" };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.IsTrue(import.RequiredMetadata.GetType() == typeof(string[]));
        }

        [Test]
        public void RequiredMetadataShouldReturnValuePassedInConstructor()
        {
            var metadata = new List<string> { "Foo", "Bar" };
            var importDescription = new ImportDescription { ContractName = "contract", RequiredMetadata = metadata };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.AreSame(import.RequiredMetadata, metadata);
        }

        [Test]
        public void ContractNameShouldReturnValuePassedInConstructor()
        {
            var importDescription = new ImportDescription { ContractName = "contract" };
            var import = new ProviderImportDefinition(GetDummyMemberInfo(), importDescription);

            Assert.AreEqual(import.ContractName, "contract");
        }

        [Test]
        public void MemberShouldReturnValuePassedInConstructor()
        {
            var member = GetDummyMemberInfo();
            var importDescription = new ImportDescription { ContractName = "contract" };
            var import = new ProviderImportDefinition(member, importDescription);

            Assert.AreEqual(import.Member, member);
        }
    }
}